#include <string.h>
#include "Exception.h"
#include "HenkoString.h"

namespace HenkoCppLib
{
	//*---------------------------------------------------
	//* String
	//*---------------------------------------------------

	String::String()
	{
		readonlystr = NULL;
	}

	String::String(int size)
	{
		str = new(str) char[size];
		str.MemSet(0);
		readonlystr = NULL;
	}

	String::String(const char* str)
	{
		readonlystr = str;
		readonlylength = strlen(str);
	}

	String::~String()
	{
	}

	int String::GetSize()
	{
		if (readonlystr)
		{
			return readonlylength;
		}
		else
		{
			return str.GetSize();
		}
	}

	int String::GetLength()
	{
		if (readonlystr)
		{
			return readonlylength;
		}
		else
		{
			return strlen(str.GetNativePointer());
		}
	}

	const char* String::GetNativePointer()
	{
		return str.GetNativePointer();
	}

	StringChar String::operator[](int index)
	{
		String s = *this;
		StringChar sc(s, index);
		return sc;
	}

	std::ostream& operator<<(std::ostream& stream, String& str)
	{
		return stream << str.GetNativePointer();
	}

	//*---------------------------------------------------
	//* StringChar
	//*---------------------------------------------------

	StringChar::StringChar(StringChar& sc)
	{
		this->str = sc.str;
		this->index = sc.index;
	}

	StringChar::StringChar(String& str, int index)
	{
		this->str = str;
		this->index = index;
	}

	bool StringChar::IsReadOnly()
	{
		return NULL == str.readonlystr;
	}

	char StringChar::GetNativeChar()
	{
		return str.str[index];
	}

	StringChar& StringChar::operator=(char c)
	{
		if (IsReadOnly())
		{
			throw ReadOnlyException();
		}

		str.str[index] = c;
		return *this;
	}

	StringChar& StringChar::operator=(StringChar c)
	{
		if (IsReadOnly())
		{
			throw ReadOnlyException();
		}

		str.str[index] = c.GetNativeChar();
		return *this;
	}

	StringChar::operator char()
	{
		return str.str[index];
	}

	std::ostream& operator<<(std::ostream& stream, StringChar& str)
	{
		return stream << str.GetNativeChar();
	}
}
